﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Data;
using PatientInformationExtract;
using System.Text.RegularExpressions;
using System.IO;
using System.Xml;
using Microsoft.Office.Interop.Excel;
using System.Windows;
using PanGu;

namespace PatientInformationExtract.MainInterface.Models.XMLCS
{
    class LabInfo : IExcelInfo
    {
        public string FileName
        {
            get
            {
                return "d_lab.XLS";
            }
        }
        private int _rowsint;
        public int RowsCount { get { return this._rowsint; } }
        private int _columnsint;
        public int ColumnsCount { get { return this._columnsint; } }
        private string _filePath;
        public string FilePath { get { return this._filePath; } }
        private string _patientID;
        public string PatientID { get { return this._patientID; } }
        private string _visitID;
        public string VisitID { get { return this._visitID; } }
        private List<XmlElement> _xmlElement;
        public List<XmlElement> XmlElements { get { return this._xmlElement; } }
        private XmlDocument _xml;
        public XmlDocument XmlDoc { get { return this._xml; } }
        private bool _isInitialized;
        public bool IsInitialized { get { return this._isInitialized; } }

        public LabInfo(XmlDocument xml)
        {
            _xml = xml;
            _patientID = null;
            _visitID = null;
            _filePath = null;
            _xmlElement = new List<XmlElement>();
            _rowsint = 0;
            _columnsint = 9;
            _isInitialized = false;
        }

        public void Initialize(string filePath, Workbooks excelWBs)
        {
            if (!_isInitialized)
            {
                FileInfo file = new FileInfo(filePath);
                if (file.Name == this.FileName)
                {
                    this._filePath = filePath;
                    ExcelOperate eO = new ExcelOperate(filePath, 2, ref excelWBs);
                    try
                    {
                        Validate(eO);
                        this._rowsint = eO.RowsCount;
                        this._patientID = eO.GetColumnStringByIndex(1);
                        this._visitID = eO.GetColumnStringByIndex(9);
                        string[] dateTime = eO.GetColumnByIndex(6);
                        string[] name = eO.GetColumnByIndex(2);
                        string[] result = eO.GetColumnByIndex(3);
                        string[] unit = eO.GetColumnByIndex(4);
                        string[] abnormal = eO.GetColumnByIndex(5);
                        string temp_dateTime = dateTime[0];
                        for (int i = 2; i <= _rowsint; i++)
                        {
                            if (!name[i - 2].Equals("其他") & !name[i - 2].Equals("其它"))
                            {
                                if (dateTime[i - 2] == "")
                                {
                                    dateTime[i - 2] = dateTime[i - 3];
                                }
                                _xmlElement.Add(NewObservationElement(dateTime[i - 2], name[i - 2], result[i - 2], unit[i - 2], abnormal[i - 2], FileName));
                            }
                        }
                        eO.Release();
                    }
                    catch (Exception ex)
                    {
                        eO.Release();
                        throw new Exception(String.Format(PatientInfoErrorMessages.InitializationFailed, FileName, ex.Message), ex);
                    }
                    _isInitialized = true;
                }
                else
                {
                    throw new Exception(String.Format(PatientInfoErrorMessages.FileNotMatch, FileName));
                }
            }
            else
            {
                throw new Exception(String.Format(PatientInfoErrorMessages.AlreadyInitialized, FileName));
            }
        }

        private void Validate(ExcelOperate excelOperate)
        {
            if (this._columnsint != excelOperate.ColumnsCount
                || excelOperate.GetCellStringByIndex(1, 1) != "patient_id"
                || excelOperate.GetCellStringByIndex(1, 2) != "report_item_name"
                || excelOperate.GetCellStringByIndex(1, 3) != "result"
                || excelOperate.GetCellStringByIndex(1, 4) != "units"
                || excelOperate.GetCellStringByIndex(1, 5) != "abnormal_indicator"
                || excelOperate.GetCellStringByIndex(1, 6) != "result_date_time"
                || excelOperate.GetCellStringByIndex(1, 7) != "test_no"
                || excelOperate.GetCellStringByIndex(1, 8) != "itemno"
                || excelOperate.GetCellStringByIndex(1, 9) != "vid"
                )
            {
                throw new Exception(String.Format(PatientInfoErrorMessages.ExcelFormatValidationFailed, FileName));
            }
        }

        private XmlElement NewObservationElement(string dateTime, string name, string result, string unit, string abnormal, string originalSource)
        {
            XmlElement observationE = _xml.CreateElement("Observation");
            XmlElement nameE = _xml.CreateElement("Name");
            XmlElement resultE = _xml.CreateElement("Result");
            XmlElement originalSourceE = _xml.CreateElement("OriginalSource");

            DateTime time = Convert.ToDateTime(dateTime);
            dateTime = time.ToString("yyyy-MM-ddTHH:mm:ssZ");
            observationE.SetAttribute("OccurTime", dateTime);
            observationE.SetAttribute("Type", "LabTest");
            nameE.InnerText = name;
            observationE.AppendChild(nameE);
            resultE.InnerText = result;
            if (unit != "")
            {
                resultE.SetAttribute("Unit", unit);
            }
            observationE.AppendChild(resultE);
            if (abnormal != "")
            {
                XmlElement abnormalE = _xml.CreateElement("Abnormal");
                abnormalE.InnerText = abnormal;
                observationE.AppendChild(abnormalE);
            }
            originalSourceE.InnerText = originalSource;
            observationE.AppendChild(originalSourceE);
            return observationE;
        }

        public System.Data.DataTable GetDataTable()
        {
            System.Data.DataTable dt = null;
            if (_filePath != null)
            {
                FullExcelOperate eO = new FullExcelOperate(_filePath, 2);
                dt = eO.ToDataTable();
                eO.Release();
                eO = null;
            }
            return dt;
        }

        public void SetXML(ref XmlDocument xml)
        {
            this._xml = xml;
        }
    }
}
